package com.silverbox.shopper.service.alipay.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.silverbox.core.util.Arith;
import com.silverbox.core.util.Utils;
import com.silverbox.shopper.dubboApi.alipay.dto.UnDiscountWaimaiItemDTO;
import com.silverbox.shopper.dubboApi.alipay.dto.UndiscountWaimaiDTO;
import com.silverbox.shopper.entity.AlipayApplyAuthToken;
import com.silverbox.shopper.entity.AlipayTradeRecord;
import com.silverbox.shopper.entity.GoodsDiscount;
import com.silverbox.shopper.entity.OrderThirdTradeRelated;
import com.silverbox.shopper.entity.PayModel;
import com.silverbox.shopper.entity.TradeFundChannel;
import com.silverbox.shopper.mapper.AlipayApplyAuthTokenMapper;
import com.silverbox.shopper.mapper.AlipayTradeRecordMapper;
import com.silverbox.shopper.mapper.CategoryDiscountMapper;
import com.silverbox.shopper.mapper.GoodsDiscountMapper;
import com.silverbox.shopper.mapper.OrderThirdTradeRelatedMapper;
import com.silverbox.shopper.mapper.PayModelMapper;
import com.silverbox.shopper.mapper.TradeFundChannelMapper;
import com.silverbox.shopper.service.alipay.AlipayService;

@Service
public class AlipayServiceImpl implements AlipayService {

	private static Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class);

	@Autowired
	private AlipayApplyAuthTokenMapper alipayApplyAuthTokenMapper;

	@Autowired
	private GoodsDiscountMapper goodsDiscountMapper;

	@Autowired
	private CategoryDiscountMapper categoryDiscountMapper;
	
	@Autowired
	private AlipayTradeRecordMapper alipayTradeRecordMapper;
	
	@Autowired
	private TradeFundChannelMapper tradeFundChannelMapper;

	@Autowired
	private PayModelMapper payModelMapper;
	
	@Autowired
	private OrderThirdTradeRelatedMapper orderThirdTradeRelatedMapper;
	
	@Override
	public List<AlipayApplyAuthToken> getAlipayApplyAuthToken(AlipayApplyAuthToken token) {
		return alipayApplyAuthTokenMapper.getAlipayApplyAuthToken(token);
	}

	@Override
	public Map<String, Object> getUnDiscountAmount(Integer storeId, Long outSupportId, UndiscountWaimaiDTO waimai,
			boolean priceFlag) {
		GoodsDiscount goodsDiscount = new GoodsDiscount();
		goodsDiscount.setType(Byte.parseByte("1"));
		goodsDiscount.setShopperChildId(storeId);
		List<GoodsDiscount> goodsDiscountList = goodsDiscountMapper.getGoodsDiscountList(goodsDiscount);
		Map<String, Object> unDiscountGoods = new HashMap<String, Object>();
		if (!Utils.isEmpty(goodsDiscountList)) {
			for (GoodsDiscount goodsTemp : goodsDiscountList) {
				// 秒付使用第三方goodsId匹配
				if (new Long(9).equals(outSupportId)) {
					if (!Utils.isEmpty(goodsTemp.getThirdGoodsId())) {
						unDiscountGoods.put(goodsTemp.getThirdGoodsId(), goodsTemp.getIsValid());
					}
				} else if (new Long(4).equals(outSupportId) || new Long(5).equals(outSupportId)) {
					if (null != goodsTemp.getGoodsId()) {
						unDiscountGoods.put(goodsTemp.getGoodsId().toString(), goodsTemp.getIsValid());
					}
				}

			}
		}
		List<String> categoryDiscountList = categoryDiscountMapper.getCategoryDiscountListByStoreId(storeId);
		Map<String, Object> unDiscountCategory = new HashMap<String, Object>();
		if (!Utils.isEmpty(categoryDiscountList)) {
			for (String categoryName : categoryDiscountList) {
				if (!Utils.isEmpty(categoryName)) {
					unDiscountCategory.put(categoryName, new Integer(1));
				}
			}
		}
		Map<String, Object> result = calculateUnDiscountAmount(waimai, unDiscountCategory, unDiscountGoods, priceFlag);
		return result;
	}

	private Map<String, Object> calculateUnDiscountAmount(UndiscountWaimaiDTO waimai,
			Map<String, Object> unDiscountCategory, Map<String, Object> unDiscountGoods, boolean priceFlag) {
		Map<String, Object> result = new HashMap<String, Object>();
		Double unDiscountAmount = 0d;
		Double totalAmount = 0d;
		List<UnDiscountWaimaiItemDTO> itemList = Utils.deepCloneObject(waimai.getItems());
		if (waimai.getOuterSupportId() == 9) {
			itemList = handleItems(itemList);
		}
		JSONArray goodsDetail = new JSONArray();
		logger.info("开始计算订单---" + waimai.getOrderNum() + "----的不打折金额");
		for (UnDiscountWaimaiItemDTO items : itemList) {
			Double buyCount = items.getBuyCount();
			String goodsId = "0";
			Double buyPrice = items.getBuyPrice();
			// 设置不上传商品单价为0的商品,false表示不上传，true为上传
			if (waimai.getOuterSupportId() == 9) {
				if (null != items.getOutGoodsId() && !"".equals(items.getOutGoodsId())) {
					goodsId = items.getOutGoodsId();
				} else if (null != items.getGoodsId() && !"".equals(items.getGoodsId())) {
					goodsId = items.getGoodsId() + "";
				}
				// 新修改：如果获取到的秒付订单中，购买数量 大于 退菜数量 并且 不是赠送菜 这样才能上传，否则这个菜品不上传
				if ((items.getBuyCount() > ((items.getRefundCount() == null ? 0 : items.getRefundCount())
						+ (items.getGive() == null ? 0 : items.getGive())))) {
					buyCount = items.getBuyCount() - ((items.getRefundCount() == null ? 0 : items.getRefundCount())
							+ (items.getGive() == null ? 0 : items.getGive()));
				} else {
					continue;
				}
				if (!priceFlag && (buyPrice == null || buyPrice == 0)) {
					continue;
				}
				totalAmount = Arith.add(totalAmount,
						(items.getBuyCount() - ((items.getRefundCount() == null ? 0 : items.getRefundCount())
								+ (items.getGive() == null ? 0 : items.getGive()))) * buyPrice);
			} else if (waimai.getOuterSupportId() == 4 || waimai.getOuterSupportId() == 5) {
				goodsId = items.getGoodsId() + "";
				// 由于我们自己系统只能全部退，所以退菜的 isRefund只能是1，0表示不是退菜 并且不是赠送菜品
				if ((null == items.getIsRefund() || 0 == items.getIsRefund())) {
					buyCount = items.getBuyCount();
				} else {
					continue;
				}
				buyPrice = (items.getOriginalPrice() == null || items.getOriginalPrice() == 0.00)
						? (items.getBuyPrice() == null ? 0.00 : items.getBuyPrice()) : items.getOriginalPrice();
				if (!priceFlag && (buyPrice == null || buyPrice == 0)) {
					continue;
				}
				totalAmount = Arith.add(totalAmount, buyPrice * buyCount);
			}
			logger.info("判断订单----" + waimai.getOrderNum() + "----中商品ID为---" + goodsId + "是否打折");
			if (unDiscountGoods.containsKey(goodsId) && 1 == new Integer(unDiscountGoods.get(goodsId).toString())) {
				unDiscountAmount = Arith.add(unDiscountAmount, (buyPrice == null ? 0.00 : buyPrice) * buyCount);
				logger.info("这个商品---" + goodsId + "---参与了不打折,金额为" + ((buyPrice == null ? 0.00 : buyPrice) * buyCount));
			} else if ((!unDiscountGoods.containsKey(goodsId)
					|| 0 != new Integer(unDiscountGoods.get(goodsId).toString())) && items.getCategoryName() != null
					&& unDiscountCategory.containsKey(items.getCategoryName())) {
				unDiscountAmount = Arith.add(unDiscountAmount, (buyPrice == null ? 0.00 : buyPrice) * buyCount);
				logger.info("这个分类---" + items.getCategoryName() + "---参与了不打折,金额为"
						+ ((buyPrice == null ? 0.00 : buyPrice) * buyCount));
			} else {
				logger.info("这个商品为---" + goodsId + "可以参加全场折扣");
			}
			//称重商品购买数量为0，不能领券
			if(buyCount!=0.0d){
				JSONObject goodsJson = new JSONObject();
				goodsJson.put("goods_id", goodsId);
				goodsJson.put("goods_name", items.getGoodsName());
				goodsJson.put("quantity", buyCount+"");
				// 加料不参与单品优惠，但参与全场优惠
				goodsJson.put("price", (buyPrice == null ? 0.00 : buyPrice)+"");
				goodsDetail.add(goodsJson);
			}
		}
		if (unDiscountAmount.doubleValue() == 0d) {
			// 如果不打折金额为空了，需要查看不打折商品列表和不打折商品分类是啥情况
			logger.info("订单----" + waimai.getOrderNum() + "---不打折金额为0,需查看不打折商品列表:"
					+ JSONObject.toJSONString(unDiscountGoods));
			logger.info("订单----" + waimai.getOrderNum() + "---不打折金额为0,需查看不打折分类列表:"
					+ JSONObject.toJSONString(unDiscountCategory));
		}
		// 过滤掉当菜品没有的情况下的上传，没有菜品，上传数据为：goods_detail:[],
		result.put("unDiscountAmount", unDiscountAmount);
		result.put("details", goodsDetail.toJSONString());
		result.put("totalAmount", totalAmount);
		return result;
	}

	private List<UnDiscountWaimaiItemDTO> handleItems(List<UnDiscountWaimaiItemDTO> itemList) {
		List<UnDiscountWaimaiItemDTO> resultList = new ArrayList<UnDiscountWaimaiItemDTO>();
		Map<String, Object> tempMap = new HashMap<String, Object>();
		if (itemList == null) {
			return new ArrayList<UnDiscountWaimaiItemDTO>();
		}
		for (UnDiscountWaimaiItemDTO item : itemList) {
			if (tempMap.containsKey(item.getOutGoodsId() + (item.getType() == null ? "" : item.getType()))) {
				UnDiscountWaimaiItemDTO temp = (UnDiscountWaimaiItemDTO) tempMap
						.get(item.getOutGoodsId() + (item.getType() == null ? "" : item.getType()));
				if (item.getBuyPrice() <= 0) {
					tempMap.put(item.getId().toString() + item.getCategoryName(), item);
					continue;
				}
				if (item.getBuyCount() < 0
						&& Math.abs(item.getBuyCount()) == (item.getRefundCount() + item.getGive())) {
					temp.setRefundCount(Arith.add(Math.abs(item.getRefundCount() == null ? 0 : item.getRefundCount()),
							temp.getRefundCount()));
					temp.setGive(Arith.add(item.getGive(), temp.getGive()));
					tempMap.put(item.getOutGoodsId() + (item.getType() == null ? "" : item.getType()), temp);
				} else if (item.getBuyCount() > 0) {
					temp.setBuyCount(Arith.add(temp.getBuyCount(), item.getBuyCount()));
					temp.setRefundCount(Arith.add(Math.abs(item.getRefundCount() == null ? 0 : item.getRefundCount()),
							temp.getRefundCount() == null ? 0 : temp.getRefundCount()));
					temp.setGive(Arith.add(item.getGive() == null ? 0 : item.getGive(),
							temp.getGive() == null ? 0 : temp.getGive()));
					tempMap.put(item.getOutGoodsId() + (item.getType() == null ? "" : item.getType()), temp);
				} else {
					tempMap.put(item.getId().toString() + item.getCategoryName(), item);
				}
			} else {
				tempMap.put(item.getOutGoodsId() + (item.getType() == null ? "" : item.getType()), item);
			}
		}
		for (Map.Entry<String, Object> entry : tempMap.entrySet()) {
			resultList.add((UnDiscountWaimaiItemDTO) entry.getValue());
		}
		return resultList;
	}

	@Override
	public int updateAlipayApplyAuthToken(AlipayApplyAuthToken token) {
		return alipayApplyAuthTokenMapper.updateByPrimaryKeySelective(token);
	}

	@Override
	public int saveAlipayTradeRecord(AlipayTradeRecord record) {
		if(record.getId()==null){
			return alipayTradeRecordMapper.insertSelective(record);
		}else{
			return alipayTradeRecordMapper.updateByPrimaryKeySelective(record);
		}
	}

	@Override
	public AlipayTradeRecord findAlipayTradeRecordByOrderNum(String orderNum,String payOrderNum) {
		return alipayTradeRecordMapper.findAlipayTradeRecordByOrderNum(orderNum,payOrderNum);
	}

	@Override
	public void insertTradeFundChannelByBatch(String orderNum, String tradeNo, Integer storeId, Integer shopperId,
			String platform, Date date, String fundBillList) {
		JSONArray ja =  JSON.parseArray(fundBillList);
    	List<TradeFundChannel> list = new ArrayList<TradeFundChannel>();
    	for(int i=0; i<ja.size(); i++){
    		JSONObject jo = ja.getJSONObject(i);
    		TradeFundChannel trade = new TradeFundChannel();
    		trade.setOrderNum(orderNum);
    		trade.setTradeNo(tradeNo);
    		trade.setAmount(jo.getDouble("amount"));
    		trade.setRealAmount(jo.getDouble("realAmount"));
    		trade.setFundChannel(jo.getString("fundChannel"));
    		trade.setPlatform(platform);
    		trade.setShopId(shopperId);
    		trade.setStoreId(storeId);
    		trade.setCreateTime(new Date());
    		list.add(trade);
    	}
		tradeFundChannelMapper.insertByBatch(list);
	}

	@Override
	public PayModel getPayCodeByPayModel(Integer payModel) {
		return payModelMapper.getPayCodeByPayModel(payModel);
	}

	@Override
	public int saveOrUpdateRecord(OrderThirdTradeRelated orderThirdTrade) {
		int count = 0 ;
		if(orderThirdTrade.getId()!=null){
			count = orderThirdTradeRelatedMapper.updateByPrimaryKeySelective(orderThirdTrade);
		}else{
			count = orderThirdTradeRelatedMapper.insertSelective(orderThirdTrade);
		}
		return count;
	}

}
